﻿$import( "SmitearWebGL.Objects.Mesh" );
$import( "SmitearWebGL.Core.Geometry.InputDataSet" );
$import( "SmitearWebGL.Core.Geometry.VertexDataSet" );

SmitearWebGL.Objects.Primitive.Plane = SmitearWebGL.Objects.Mesh.extend(
{
	/* * * * * * * * constructor * * * * * * * */

	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Objects.Primitive.Plane" );
	}
	,
	_build : function( width, height, segmentsW, segmentsH )
	{
		var gridX = segmentsW;
		var gridY = segmentsH;
		var gridX1 = gridX + 1;
		var gridY1 = gridY + 1;

		var vertices = new Array( gridX1 * gridY1 * 3 );
		var uvs = new Array( gridX * gridY * 6 * 3 );
		var vIndices = new Array( gridX * gridY * 6 );
		var tIndices = new Array( gridX * gridY * 6 );
		var k = 0, l = 0, m = 0;

		var textureX = width / 2;
		var textureY = height / 2;

		var iW = width / gridX;
		var iH = height / gridY;

		// Vertices
		for( var ix = 0; ix < gridX1; ix ++ )
		{
			for( var iy = 0; iy < gridY1; iy ++ )
			{
				var x = ix * iW - textureX;
				var y = iy * iH - textureY;
					
				vertices[k++] = x;
				vertices[k++] = y;
				vertices[k++] = 0.0;
			}
		}

		// Faces
		k = 0;

		for( ix = 0; ix < gridX; ix ++ )
		{
			for( iy = 0; iy < gridY; iy ++ )
			{
				// Triangle A
				vIndices[l + 0] = ix       * gridY1 + iy ;
				vIndices[l + 1] = ( ix + 1 ) * gridY1 + iy;
				vIndices[l + 2] = ix       * gridY1 + ( iy + 1 );
				
				uvs[m + 0] = ix / gridX;
				uvs[m + 1] = iy / gridY;
				uvs[m + 2] = 0.0;
				uvs[m + 3] = ( ix + 1 ) / gridX;
				uvs[m + 4] = iy / gridY;
				uvs[m + 5] = 0.0;
				uvs[m + 6] = ix / gridX;
				uvs[m + 7] = ( iy + 1 ) / gridY;
				uvs[m + 8] = 0.0;
				
				tIndices[l + 0] = k ++;
				tIndices[l + 1] = k ++;
				tIndices[l + 2] = k ++;
				
				// Triangle B
				vIndices[l + 3] = ( ix + 1 ) * gridY1 + ( iy + 1 );
				vIndices[l + 4] = ix       * gridY1 + ( iy + 1 );
				vIndices[l + 5] = ( ix + 1 ) * gridY1 + iy;
				
				uvs[m + 9] = ( ix + 1 ) / gridX;
				uvs[m + 10] = ( iy + 1 ) / gridY;
				uvs[m + 11] = 0.0;
				uvs[m + 12] = ix / gridX;
				uvs[m + 13] = ( iy + 1 ) / gridY;
				uvs[m + 14] = 0.0;
				uvs[m + 15] = ( ix + 1 ) / gridX;
				uvs[m + 16] = iy / gridY;
				uvs[m + 17] = 0.0;
				
				tIndices[l + 3] = k ++;
				tIndices[l + 4] = k ++;
				tIndices[l + 5] = k ++;
				
				l += 6;
				m += 18;
			}
		}
		
		this._vertices = vertices;
		this._indices = vIndices;
			
		var inputDatas = [
			new SmitearWebGL.Core.Geometry.InputDataSet( vIndices, vertices, 3 ),
			new SmitearWebGL.Core.Geometry.InputDataSet( tIndices, uvs, 3 )
		];
		
		var vOutputData = SmitearWebGL.Core.Geometry.Geometry.buildRawData( inputDatas );
		
		var vAdj = SmitearWebGL.Core.Geometry.Geometry.buildVertexAdjancency( inputDatas[0] );
		var fNormals = SmitearWebGL.Core.Geometry.Geometry.buildFaceNormal( inputDatas[0] );
		var nOutpuData = SmitearWebGL.Core.Geometry.Geometry.buildVertexNormal( inputDatas[0], vAdj, fNormals, new SmitearWebGL.Core.Geometry.InputDataSet( vOutputData.indices, null, 3 ) );
		
		var rawData = SmitearWebGL.Core.Geometry.Geometry.combineVertexDatas( [
			new SmitearWebGL.Core.Geometry.VertexDataSet( vOutputData.data, 6 ),
			new SmitearWebGL.Core.Geometry.VertexDataSet( nOutpuData.data, 3 ),
		] );
		
		this._boundingBox = SmitearWebGL.Core.Geometry.Geometry.computeBoundingBoxByRawVertices( vertices );
		
		var vertDescs = [
			new SmitearWebGL.Resources.VertexElementDescription( this.context.gl, 3, 36, 0, SmitearWebGL.Resources.Buffer.DataType.FLOAT, SmitearWebGL.Resources.Buffer.AttribLocation.POSITION ),
			new SmitearWebGL.Resources.VertexElementDescription( this.context.gl, 3, 36, 12, SmitearWebGL.Resources.Buffer.DataType.FLOAT, SmitearWebGL.Resources.Buffer.AttribLocation.TEXCOORD ),
			new SmitearWebGL.Resources.VertexElementDescription( this.context.gl, 3, 36, 24, SmitearWebGL.Resources.Buffer.DataType.FLOAT, SmitearWebGL.Resources.Buffer.AttribLocation.NORMAL )
		]
		
		var idxDescs = [
			new SmitearWebGL.Resources.IndexElementDescription( this.context.gl, vOutputData.indices.length, 0, SmitearWebGL.Resources.Buffer.DataType.UNSIGNED_SHORT, SmitearWebGL.Resources.IndexBuffer.DrawType.TRIANGLES )
		]
		
		this.createVertexBuffer( rawData, vertDescs );
		this.createIndexBuffer( vOutputData.indices, idxDescs );
	}
	,
	_createResource : function( params )
	{
		this._super();
		
		if ( ! params )
		{
			params = {};
			params.width = 1.0;
			params.height = 1.0;
			params.segmentsW = 1.0;
			params.segmentsH = 1.0;
		}
		
		this._build( params.width, params.height, params.segmentsW, params.segmentsH );
	}
}
);